package cn.dubnation.org.service.impl;

import cn.dubnation.base.constants.SystemConstants;
import cn.dubnation.base.enums.ResponseCode;
import cn.dubnation.base.exception.BusinessException;
import cn.dubnation.base.util.audit.ActiveCode;
import cn.dubnation.base.util.audit.ErrorInfo;
import cn.dubnation.org.domain.Employee;
import cn.dubnation.org.domain.Shop;
import cn.dubnation.org.domain.ShopOperateLog;
import cn.dubnation.org.mapper.EmployeeMapper;
import cn.dubnation.org.mapper.ShopMapper;
import cn.dubnation.org.service.IEmployeeService;
import cn.dubnation.base.service.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zhu
 * @since 2023-12-29
 */
@Service
@Transactional
public class EmployeeServiceImpl extends BaseServiceImpl<Employee> implements IEmployeeService {

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired(required = false)
    private EmployeeMapper employeeMapper;

    @Autowired(required = false)
    private ShopMapper shopMapper;

    @Autowired
    private ShopOperateLog shopOperateLog;

    @Autowired
    private ActiveCode activeCode;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 发送驳回邮件
     * @param errorInfo
     */
    @Override
    public void sendRejectEmail(ErrorInfo errorInfo) {
        //1.根据用户id查看店铺管理员邮件是否可用
        Employee employee = employeeMapper.queryById(errorInfo.getAdminId());
        String mailName = "^[0-9a-z]+\\w*";       //^表明一行以什么开头；^[0-9a-z]表明要以数字或小写字母开头；\\w*表明匹配任意个大写小写字母或数字或下划线
        String mailDomain = "([0-9a-z]+\\.)+[0-9a-z]+$";       //***.***.***格式的域名，其中*为小写字母或数字;第一个括号代表有至少一个***.匹配单元，而[0-9a-z]$表明以小写字母或数字结尾
        String mailRegex = mailName + "@" + mailDomain;          //邮箱正则表达式      ^[0-9a-z]+\w*@([0-9a-z]+\.)+[0-9a-z]+$
        Pattern pattern = Pattern.compile(mailRegex);
        Matcher matcher = pattern.matcher(employee.getEmail());
        if (!matcher.matches()){
            //邮箱格式不正确
            throw new BusinessException(ResponseCode.RESPONSE_CODE_400006);
        }
        try {
            //2.邮箱格式正确, 可以发送邮件
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
            //发件人和收件人
            mimeMessageHelper.setFrom("3515623332@qq.com");
            mimeMessageHelper.setTo(employee.getEmail());
            //主题
            mimeMessageHelper.setSubject(errorInfo.getDetailedMsg());
            String url = "http://127.0.0.1:8083/#/shopRegister?shopId=";
            //文本
            mimeMessageHelper.setText("请点击链接地址修改店铺信息:" +
                    "<a href='"+ url + errorInfo.getShopId() +"'>'"+ url + errorInfo.getShopId() +"'</a>", true);
            //发送邮件
            javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
            throw new BusinessException("发送驳回邮件失败!");
        }
        //4.修改店铺状态为驳回, 驳回次数加1, 管理员状态为锁定
        Shop shop = shopMapper.queryById(errorInfo.getShopId());
        shop.setState(SystemConstants.Shop.REJECT);
        Integer rejectedNum = shop.getRejectedNum();
        rejectedNum += 1;
        shop.setRejectedNum(rejectedNum);
        shopMapper.update(shop);
        employee.setState(SystemConstants.Employee.UNAVAILABLE);
        employeeMapper.update(employee);
        //5.记录驳回日志
        shopOperateLog.setShopId(shop.getId());
        shopOperateLog.setOperateId(employee.getId());
        shopOperateLog.setOperateType(SystemConstants.ShopOperateLog.AUDIT_REJECT);
        shopOperateLog.setNote("审核驳回, " + errorInfo.getErrorType());
        shopOperateLog.setOperateTime(new Date());
    }

    /**
     * 发送激活邮件
     * @param shop
     */
    @Override
    public void sendPassEmail(Shop shop) {
        //1.判断管理员邮箱是否可以发送邮件
        Employee admin = shop.getAdmin();
        String mailName = "^[0-9a-z]+\\w*";       //^表明一行以什么开头；^[0-9a-z]表明要以数字或小写字母开头；\\w*表明匹配任意个大写小写字母或数字或下划线
        String mailDomain = "([0-9a-z]+\\.)+[0-9a-z]+$";       //***.***.***格式的域名，其中*为小写字母或数字;第一个括号代表有至少一个***.匹配单元，而[0-9a-z]$表明以小写字母或数字结尾
        String mailRegex = mailName + "@" + mailDomain;          //邮箱正则表达式      ^[0-9a-z]+\w*@([0-9a-z]+\.)+[0-9a-z]+$
        Pattern pattern = Pattern.compile(mailRegex);
        Matcher matcher = pattern.matcher(admin.getEmail());
        if (!matcher.matches()){
            //邮箱格式不正确
            throw new BusinessException(ResponseCode.RESPONSE_CODE_400006);
        }
        //邮箱格式正确
        //2.将店铺id和管理员id以激活码的形式封装成一个类, 并存储到redis中设置过期时间
        activeCode.setShopId(shop.getId());
        activeCode.setEmployeeId(admin.getId());
        redisTemplate.opsForValue().set(SystemConstants.Employee.ACTIVE_CODE, activeCode, 30, TimeUnit.MINUTES);
        try {
            //3.发送激活邮件
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
            mimeMessageHelper.setFrom("3515623332@qq.com");
            mimeMessageHelper.setTo(admin.getEmail());
            //发送主题
            mimeMessageHelper.setSubject("恭喜您注册的店铺审核通过，您现在可以激活店铺以及管理员账户！");
            /*
             * 发送html文本
             * 发送的激活地址中需要携带参数--shopId和employeeId--用redis封装
             * */
            String url = "http://127.0.0.1:8085/shop/active?code=" + SystemConstants.Employee.ACTIVE_CODE;
            mimeMessageHelper.setText("请在72小时之内点击链接" +
                    "<a href='"+ url +"'>'"+ url +"'</a>" + "进行店铺和管理账户激活。", true);
            //发送
            javaMailSender.send(mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
            throw new BusinessException(ResponseCode.RESPONSE_CODE_400006);
        }
        //4.更改店铺状态为审核通过待激活
        shop.setState(SystemConstants.Shop.TO_BE_ACTIVATED);
        //5.记录通过激活日志
        shopOperateLog.setShopId(shop.getId());
        shopOperateLog.setOperateTime(new Date());
        shopOperateLog.setNote("系统审核通过");
        shopOperateLog.setOperateType(SystemConstants.ShopOperateLog.AUDIT_SUCCESS);
        shopOperateLog.setOperateId(admin.getId());
    }
}
